﻿using AutoMapper;
using Core.SimpleTemp.Application.SysApp.DepartmentApp.Dtos;
using Core.SimpleTemp.Common;
using Core.SimpleTemp.Common.PagingQuery;
using Core.SimpleTemp.Entitys;
using Core.SimpleTemp.Repositories.RepositoryEntityFrameworkCore.Sys;
using Core.Toolkit.AutoMapperExtend.DataDictionary;
using Core.Toolkit.Core;
using Core.Toolkit.Core.Api;
using Core.Toolkit.Core.Application;
using Core.Toolkit.Core.Entitys;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace Core.SimpleTemp.Application
{
    [AutoDi()]
    [AutoDi(typeof(IConcurrentDataDicProvider))]
    public class SysDepartmentAppService : BaseAppService<SysDepartmentDto, SysDepartment, SysDepartmentRepository>, IConcurrentDataDicProvider
    {
        public SysDepartmentAppService(SysDepartmentRepository repository) : base(repository)
        {
        }
        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="pagingQueryModel">分页及查询条件对象，此处未重写的分页条件对象，放宽了每页显示数量，用于部分页情况</param>
        /// <returns></returns>
        public async Task<IPageModel<SysDepartmentDto>> GetList(DepartmentPagingModel<SysDepartmentDto> pagingQueryModel)
        {
            var loadPageOffsetModel = this.GetLoadPageOffsetModelAuto(pagingQueryModel);
            this.GetLoadPageOffsetModel(pagingQueryModel);
            loadPageOffsetModel.Limit = 1000;
            //基础查询，联表查询在此操作
            var baseQuery = _repository.QueryBase().AsNoTracking();
            //查询条件
            loadPageOffsetModel.QueryWhere = this.CreateQRList().Add(nameof(SysDepartmentDto.Name), "in").Add(nameof(SysDepartmentDto.Code), "in").Add(nameof(SysDepartmentDto.CreateFactory), "=");
            loadPageOffsetModel.BasqQuery = baseQuery;
            //排序
            loadPageOffsetModel.Order = orderModel => orderModel.Sort;
            //指定查询字段 
            loadPageOffsetModel.Selector = u => new SysDepartment()
            {
                Id = u.Id,
                Name = u.Name,
                Code = u.Code,
                CreateFactory = u.CreateFactory,
                Remark = u.Remark,
                ParentId = u.ParentId,
                Sort = u.Sort,
                IsDeleted = u.IsDeleted
            };

            //Task<IPageModel<SysDepartmentDto>> res =  base.LoadPageOffsetAsync(loadPageOffsetModel);
            //return null;
            return await base.LoadPageOffsetAsync(loadPageOffsetModel);
        }

        #region 删除操作
        /// <summary>
        /// 逻辑删除，继承自基础服务类物理删除方法并重写调用基础仓储类逻辑删除方法
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="autoSave"></param>
        /// <returns></returns>
        public override async Task DeleteBatchAsync(Guid[] ids, bool autoSave = true)
        {
            foreach (Guid item in ids)
            {
                //调用基础仓储类中的逻辑删除方法
                await _repository.DeleteLogicAsync(item);
            }
        }



        /// <summary>
        /// 实际删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="autoSave"></param>
        /// <returns></returns>
        //public override async Task DeleteAsync(Guid id, bool autoSave = true)
        //{
        //    await _repository.DeleteLogicAsync(it => id == it.Id, autoSave);
        //}
        #endregion

        //Get接口
        public async Task<SysDepartment> GetAsync(Guid id)
        {
            var baseQuery = _repository.QueryBase().Include(a => a.SysDepartmentDuties).ThenInclude(b => b.SysDuty);

            baseQuery.Select(a => new
            {
                a.Name,
                a.CreateFactory,
                Duties = a.SysDepartmentDuties.Select(c => new
                {
                    c.SysDuty.Name,
                    c.SysDuty.Id,
                    c.SysDuty.Position
                }).OrderBy(x => x.Position).ToArray()
            });

            return await GetAsync(id, baseQuery);
        }

        /// <summary>
        /// 更新部门职务关联关系
        /// </summary>
        /// <param name="SysDepartmentID">部门id</param>
        /// <param name="DepartmentDutys">职务集合</param>
        /// <returns></returns>
        public async Task<bool> UpdateDepartmentDutyAsync(Guid SysDepartmentID, List<SysDepartmentDutyDto> DepartmentDutys)
        {
            return await _repository.UpdateDepartmentDutyAsync(SysDepartmentID, Mapper.Map<List<SysDepartmentDuty>>(DepartmentDutys));
        }



        #region 字典池与热更新

        public const string DIC_CATEGORY_CODE = "9009";
        /// <summary>
        /// 继承接口
        /// </summary>
        /// <param name="_dataDic"></param>
        /// <param name="_dataDicListByCategory"></param>
        public void LoadData(ConcurrentDictionary<string, string> _dataDic, ConcurrentDictionary<string, List<DataDicModel>> _dataDicListByCategory)
        {
            var list = _repository.Set.ToList();
            foreach (var item in list)
            {
                _dataDic.TryAdd($"{DIC_CATEGORY_CODE}_{item.Id}", item.Name);
            }
            _dataDicListByCategory.TryAdd(DIC_CATEGORY_CODE, list.Select(sdd => new DataDicModel()
            {
                Category = DIC_CATEGORY_CODE,
                Key = sdd.Id + "",
                Value = sdd.Name
            }).ToList());
        }

        /// <summary>
        ///// 热更新DataDic池
        ///// </summary>
        ///// <param name="userId"></param>
        ///// <param name="Name"></param>
        //private void UpdateDataDidcPoll(string code, string value)
        //{
        //    var key = ConcurrentDataDicPool.CreateKey(DIC_CATEGORY_CODE, code.ToString());
        //    ConcurrentDataDicPool.UpdateDataDic(key, value);
        //} 
        #endregion
    }
}
